import UIContainer from './UIContainer';
import UIUtils from './UIUtils';
import UIManager from './UIManager';
import UIWatcher from './UIWatcher';
import { AnimationType } from '../NeedChange/UIConfig';
import { UIAnimation } from './UIAnimation';
const { ccclass, property } = cc._decorator;

@ccclass
export default class UIBase extends cc.Component {
    //作为所有UI页面的基类，放公共的部分
    protected _uiContainer: UIContainer = new UIContainer();
    private _uiName: string = ""
    get uiName() {
        return this._uiName;
    }
    set uiName(name) {
        this._uiName = name;
    }
    init(...rest: any[]) {
        UIUtils.findNode(this.node, this._uiContainer);
        this.onInit.apply(this, arguments);
    }
    //一个UI可能会有多个观察者,存储这个UI上的所有观察者
    private _arrWatcher: UIWatcher[] = [];

    @property({ type: cc.Enum(AnimationType), displayName: "动画选择", tooltip: "退场和入场动画选择:fade淡入淡出动画……" })
    animationType: AnimationType = AnimationType.none;

    private _uiAnimation: UIAnimation = null;
    playAnimation(openOrClose: string, animationIndex: number, cb: Function) {
        // 直接实例化，无需传递this
        const uiAnimation = new UIAnimation();
        uiAnimation.playAnimation(this, openOrClose, animationIndex, cb);
    }

    //给派生类重写
    onInit(...rest: any[]) {

    }

    //每个页面控制自己的开与关
    open(isClose: boolean, isDestroy: boolean, ...rest: any[]) {
        if (!this.node.active) {
            this.node.active = true;
        }
        // this.onEnter.apply(this, rest);
        // if (isClose) {
        //     rest.unshift(isDestroy);
        //     this.close.apply(this, rest);
        // }
        this.playAnimation("open", this.animationType, () => {
            this.onEnter.apply(this, rest);
            if (isClose) {
                rest.unshift(isDestroy);
                this.close.apply(this, rest);
            }
        })

    }

    close(isDestroy: boolean = false, ...rest: any[]) {
        this.onExit.apply(this, rest);
        // if (!isDestroy) {
        //     if (this.node.active) {
        //         this.node.active = false;
        //     }
        //     return;
        // }
        // //将UI上的所有观察者都销毁
        // for (let watcher of this._arrWatcher) {
        //     watcher.removeself();
        // }
        // this.node.destroy();
        this.playAnimation("close", this.animationType, () => {
            if (!isDestroy) {
                if (this.node.active) {
                    this.node.active = false;
                }
                return;
            }
            //将UI上的所有观察者都销毁
            for (let watcher of this._arrWatcher) {
                watcher.removeself();
            }
            this.node.destroy();
        })

    }

    openUI(uiName: string, isClose: boolean = false, isDestroy: boolean = false, bundleName?: string, layerName: string = "Normal", ...rest: any[]) {
        let bundleN = bundleName || "UI";
        let args: any[] = [];
        for (let value of rest) {
            args.push(value);
        }
        args.unshift(layerName);
        args.unshift(bundleN);
        args.unshift(uiName);
        UIManager.instance.openUI.apply(UIManager.instance, args);

        if (isClose) {
            rest.unshift(isDestroy);
            rest.unshift(this.uiName);
            this.closeUI.apply(this, rest);
        }
    }

    closeUI(uiName: string, isDestroy: boolean = false, ...rest: any[]) {
        UIManager.instance.closeUI.apply(UIManager.instance, arguments);

    }

    closeSelf(isDestroy: boolean, ...rest: any[]) {
        rest.unshift(isDestroy);
        rest.unshift(this.uiName);
        this.closeUI.apply(this, rest);
    }

    //每次打开页面都让派生类重写一次
    onEnter(...rest: any[]) {

    }

    //每次退出让派生类重写一次
    onExit(...rest: any[]) {

    }

    //默认回调接口
    handleMsg(...rest: any[]) {

    }

    //绑定回调
    bindCb(data: Object, key: string, cb: Function, target?: any, comp?: cc.Component) {
        target = target || this;
        //创建一个观察者
        let watcher = new UIWatcher(data, key, target, cb, comp);
        //这个UI上增加了一个观察者，需要将这个观察者存入到这个UI存取观察者的地方，方便后续这个UI销毁时将这个UI上的观察者全部销毁
        this._arrWatcher.push(watcher);
    }

    bindComp(data: Object, key: string, comp: cc.Component, target?: any) {
        this.bindCb(data, key, UIUtils.refreshComp, target, comp);
    }
    //消息机制
    sendMsg(msgName: string, uiName: string, ...rest: any[]) {
        UIManager.instance.sendMsg.apply(UIManager.instance, arguments);
    }
    //事件监听
    onEventListener(nodeName: string, eventName: string, cb: Function) {
        let node = this.getNode(nodeName);
        if (!node) {
            cc.error(nodeName + "节点名字有误");
            return;
        }
        node.on(eventName, cb, this);
        this.node.on(eventName, cb, this)
    }

    //点击事件的监听
    onClickListner(nodeName: string, cb: Function) {
        this.onEventListener(nodeName, "click", cb);
    }

    //获取组件
    getComp<T>(nodeName: string, compName: string): T {
        return this._uiContainer.getComp(nodeName, compName) as T;
    }

    //获取节点
    getNode(nodeName: string) {
        return this._uiContainer.getNode(nodeName);
    }


}


